package com.sentiment.database.bean;

import java.util.ArrayList;
import java.util.List;

import org.bson.Document;import org.bson.types.ObjectId;
import org.bson.types.ObjectId;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.sentiment.bean.OperationInfo;
import com.sentiment.database.dbUtil.DbUtil;

public class Role {
	@Override
	public String toString() {
		return "Role [_id=" + _id + ", rolename=" + rolename + ",role_detail=" + role_detail +"]";
	}
	
	public Role() {
		// TODO Auto-generated constructor stub
	}

	public static final String dbName = "UserDB";
	public static final String collection = "Role";
	
	private ObjectId _id;
	private String rolename;
	private String role_detail;
	
	public Role(Document doc){
		super();
		_id = doc.getObjectId("_id");
		rolename = doc.getString("rolename");
		role_detail = doc.getString("role_detail");
	}
	
	public Role(String id){
		super();
		this._id = new ObjectId(id);
		
	}
	
	public Document toDocument(){
		return new Document("rolename", rolename).append("role_detail", role_detail);
	}
	
	public String getRole_detail() {
		return role_detail;
	}

	public void setRole_detail(String role_detail) {
		this.role_detail = role_detail;
	}

	public void set_id(ObjectId _id) {
		this._id = _id;
	}

	public String get_id() {
		return _id.toString();
	}

	public void set_id(String _id) {
		this._id = new ObjectId(_id);
	}

	public String getRolename() {
		return rolename;
	}

	public void setRolename(String rolename) {
		this.rolename = rolename;
	}

	public Role(String rolename, String role_detail) {
		super();
		this.rolename = rolename;
		this.role_detail = role_detail;
	}
	
	/**
	 * 用于测试时向数据库中写入数据
	 */
	public void test() {
		DbUtil roledb = new DbUtil();
		roledb.openConnection(dbName, collection);
		
		Role role = new Role("admin","管理员");
		Document t = role.toDocument();
		roledb.insert(t);
		
		role = new Role("nopay","免费用户");
		t = role.toDocument();
		roledb.insert(t);
		
		role = new Role("pay","付费用户");
		t = role.toDocument();
		roledb.insert(t);
		
		roledb.closeConnection();
		
	}
	
	/**
	 * 根据 RoleName 获取 Role 对象
	 * @param RoleName
	 * @return
	 */
	public Role getRoleByRoleName(String RoleName) {
		DbUtil db = new DbUtil();
		db.openConnection(dbName, collection);
		
		String[] keys = {"rolename"};
		Role role = new Role(RoleName,null);
		Document t = role.toDocument();
		t = db.query(t,keys);
		
		db.closeConnection();
		
		if(t == null)
			return null;
		
		return new Role(t);
	}
	
	/**
	 * 根据 role_detail 获取 Role 对象
	 * @param role_detail
	 * @return
	 */
	public Role getRoleByRole_detail(String role_detail) {
		DbUtil db = new DbUtil();
		db.openConnection(dbName, collection);
		
		String[] keys = {"role_detail"};
		Role role = new Role(null,role_detail);
		Document t = role.toDocument();
		t = db.query(t,keys);
		
		db.closeConnection();
		
		if(t == null)
			return null;
		
		return new Role(t);
	}
	
	/**
	 * 根据 Role_id 获取 Role
	 * @param id
	 * @return
	 */
	public Role getRoleByRoleId(String id) {
		
		DbUtil db = new DbUtil();
		db.openConnection(dbName, collection);
		
		String[] keys = {"_id"};
		Role role = new Role(id);
		Document t = role.toDocument_id();
		t = db.query(t,keys);
		
		db.closeConnection();
		
		if(t == null)
			return null;
		
		return new Role(t);
		
	}

	/**
	 * 获取 Role 表中数据条数
	 * @return
	 */
	@JsonIgnore
	public long getCount(){
		
		DbUtil db = new DbUtil();
		db.openConnection(dbName, collection);
		long count = db.collectionGetCount();
		db.closeConnection();
		return count;
		
	}
	
	/**
	 * 当前角色移除某一权限，包括 Role_Permissions、 User_Permissions 表
	 * 权限存在于数据库中
	 * @param per_id 权限 id
	 * @return
	 */
	public String removePer(String per_id){
		
		DbUtil db = new DbUtil();
		db.openConnection(Role_Permissions.dbName, Role_Permissions.collection);
		//Role_Permissions 表
		Role_Permissions role_pers = new Role_Permissions();
		role_pers = role_pers.getRole_PermissionsByRole_id(this.get_id());
		if(role_pers == null){
			return OperationInfo.RoleNotFound;
		}else{
			List<String> listpersid = role_pers.getPermission_id();
			if(!listpersid.contains(per_id)){
				return OperationInfo.RoleNotContainPer;
			}else{
				listpersid.remove(per_id);
				
				String []okeys = {"role_id"};
				String []nkeys = {"permission_id"};
				Boolean updateRole_Pers = db.update(role_pers.toDocument(), okeys, role_pers.toDocument(), nkeys);
				
				if(!updateRole_Pers){
					return OperationInfo.OperFailure;
				}
			}
		}

		//User_Permissions 表
		
		//得到包含该权限的 Role_id(list)
		List<String> listrole_id = new ArrayList<>();		
		List<Document> tlistrole_pers = new ArrayList<>();
		tlistrole_pers = db.queryByOneinList("permission_id", per_id);
		db.closeConnection();
		for (int i = 0; i < tlistrole_pers.size(); i++) {
			role_pers = new Role_Permissions(tlistrole_pers.get(i));
			listrole_id.add(role_pers.getRole_id());
		}
		//得到包含该角色的 User_id(list) -> 判断用户是否确实无该权限  -> 修改 User_Permissions 表
		db.openConnection(User_Roles.dbName, User_Roles.collection);
		List<Document> tlistuser_roles = new ArrayList<>();
		tlistuser_roles = db.queryByOneinList("roles_id", this.get_id());
		db.closeConnection();
		if(tlistuser_roles.size() != 0){
			for (int i = 0; i < tlistuser_roles.size(); i++) {
				User_Roles user_roles = new User_Roles(tlistuser_roles.get(i));
				List<String> listuserrolesid = new ArrayList<>();
				listuserrolesid = user_roles.getRoles_id();
				//用户的角色和包含该权限的角色取交集，如果交集后的list.size为0，则判断为用户不包含该权限
				listuserrolesid.retainAll(listrole_id);
				if(listuserrolesid.size() == 0){
					//更新 User_Permissions 表
					User_Permissions user_pers = new User_Permissions();
					user_pers = user_pers.getUser_PermissionsByUser_id(user_roles.getUser_id());
					user_pers.getpermissions_id().remove(per_id);
					db.openConnection(User_Permissions.dbName, User_Permissions.collection);
					String []okeys = {"user_id"};
					String []nkeys = {"permissions_id"};
					db.update(user_pers.toDocument(), okeys, user_pers.toDocument(), nkeys);
					db.closeConnection();
				}
			}
		}else{
			return OperationInfo.OperSuccess;
		}
		
		
		return OperationInfo.OperSuccess;
	}
	
	/**
	 * 当前角色增加某一权限，包括 Role_Permissions、 User_Permissions 表
	 * 权限存在于数据库中
	 * @param per_id 权限 id
	 * @return
	 */
	public String addPer(String per_id){
		
		DbUtil db = new DbUtil();
		
		//Role_Permissions 表
		Role_Permissions role_pers = new Role_Permissions();
		role_pers = role_pers.getRole_PermissionsByRole_id(this.get_id());
		if(role_pers == null){
			return OperationInfo.RoleNotFound;
		}else{
			List<String> listpersid = role_pers.getPermission_id();
			if(listpersid.contains(per_id)){
				return OperationInfo.RolehasContainPer;
			}else{
				listpersid.add(per_id);
				db.openConnection(Role_Permissions.dbName, Role_Permissions.collection);
				String []okeys = {"role_id"};
				String []nkeys = {"permission_id"};
				Boolean updateRole_Pers = db.update(role_pers.toDocument(), okeys, role_pers.toDocument(), nkeys);
				db.closeConnection();
				if(!updateRole_Pers){
					return OperationInfo.OperFailure;
				}
			}
		}
		
		//User_Permissions 表
		
		//得到包含该角色的 User_id(list)
		db.openConnection(User_Roles.dbName, User_Roles.collection);
		List<Document> tlistuser_roles = new ArrayList<>();
		tlistuser_roles = db.queryByOneinList("roles_id", this.get_id());
		db.closeConnection();
		List<String> listuser_id = new ArrayList<>();
		if(tlistuser_roles.size() != 0){
			for (int i = 0; i < tlistuser_roles.size(); i++) {
				User_Roles user_roles = new User_Roles(tlistuser_roles.get(i));
				listuser_id.add(user_roles.getUser_id());							
			}
		}else{
			return OperationInfo.OperSuccess;
		}		
		//开始修改 User_Permission 表
		for (int i = 0; i < listuser_id.size(); i++) {
			User_Permissions user_pers = new User_Permissions();
			user_pers = user_pers.getUser_PermissionsByUser_id(listuser_id.get(i));
			if(!user_pers.getpermissions_id().contains(per_id)){
				user_pers.getpermissions_id().add(per_id);
				db.openConnection(User_Permissions.dbName, User_Permissions.collection);
				String []okeys = {"user_id"};
				String []nkeys = {"permissions_id"};
				db.update(user_pers.toDocument(), okeys, user_pers.toDocument(), nkeys);
				db.closeConnection();
			}
		}
		
		
		return OperationInfo.OperSuccess;
	}
	
	/**
	 * 删除当前角色
	 * @return 操作信息
	 */
	public String deleteRole(){
		
		Role roledb = new Role();
		roledb = roledb.getRoleByRoleId(this.get_id());
		if(roledb == null){
			
			return OperationInfo.RoleNotFound;
		}
		
		//删除 Role 表中数据
		DbUtil db = new DbUtil();
		db.openConnection(dbName, collection);
		
		String []keys = {"_id"};
		boolean brole = db.remove(this.toDocument_id(), keys);
		
		db.closeConnection();
		
		//删除 Role_Permissions 表中数据
		Role_Permissions role_pers = new Role_Permissions();
		boolean brole_per = role_pers.deleteRole_PersByRole(this);
		
		//删除 User_Roles 表中数据
		User_Roles user_roles = new User_Roles();
		boolean buser_role = user_roles.deleteRole(this);
		
		if(brole && brole_per && buser_role)
			return OperationInfo.OperSuccess;
		else
			return OperationInfo.OperFailure;
		
	}
	
	
	
	@Override
	public boolean equals(Object obj) {

		 if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Role other = (Role) obj;
        if (_id == null) {
            if (other._id != null)
                return false;
        } else if (!_id.equals(other._id))
            return false;
        
        if (rolename == null) {
            if (other.rolename != null)
                return false;
        } else if (!rolename.equals(other.rolename))
            return false;
        
        if (role_detail == null) {
            if (other.role_detail != null)
                return false;
        } else if (!role_detail.equals(other.role_detail))
            return false;
        
        return true;
	}

	public Document toDocument_id() {
		return new Document("_id", _id).append("rolename", rolename).append("role_detail", role_detail);
	}
	
	public static void main(String[] args) {
		
		Role role = new Role();
		role = role.getRoleByRoleId("56499f4ddad764200c7c5899");		
		System.out.println(role.addPer("56499f4ddad764200c7c589e"));
	}
	
}
